/*
 * gui_lua.c
 */

#include <stdlib.h>
#include <lua/luaR.h>
#include <utils/error.h>
#include "gui.h"
#include "gui_lua.h"
#include <agent/player.h>

static int gui_lua_initialized = 0;

static unit *player;

/*
 * Lua hook to the function:
 * load_png(const char *filename);
 */
int gui_lua_loadPng( lua_State *L ) {
    const char *filename;
    int index;
    if( lua_gettop(L) == 0 ) {
        lua_pushstring(L, "Too few arguments");
        lua_error(L);
    }
    else {
        filename = lua_tostring(L, 1);
        index = load_png(filename);
        lua_pop(L, lua_gettop(L)); /* Clear stack */
        lua_pushnumber(L, index);
        return 1;
    }
    return 0; /* Shouldn't happen */
}

/*
 * Lua hook to the function:
 * gui_draw_texture( int x, int y, int texture );
 */
int gui_lua_drawTexture( lua_State *L ) {
    int x;
    int y;
    int index;
    if( lua_gettop(L) < 3 ) {
        lua_pushstring(L, "Too few arguments");
        lua_error(L);
    }
    else {
        x = lua_tonumber(L, 1);
        y = lua_tonumber(L, 2);
        index = lua_tonumber(L, 3);
        gui_draw_texture(x, y, index);
        return 0;
    }
    return 0; /* Shouldn't happen */
}

/*
 * Lua hook to the function:
 * gui_draw_healthbar( int x, int y, int width, int height, int hp, int max );
 */
int gui_lua_drawHealthBar( lua_State *L ) {
    int x;
    int y;
    int width;
    int height;
    int hp;
    int max;
    /*
    player = player_get();
    hp = ((go_stats*)player->stats)->hp;
    max = ((go_stats*)player->stats)->hp_max;
    */
    /* Fill in defaults as necessary */
    switch (lua_gettop(L)) {
        case 0:
        case 1:
        case 2:
        case 3:
            lua_pushstring(L, "Too few arguments");
            lua_error(L);
        case 4:
            width = 50;
            height = 10;
            break;
        case 5:
            width = lua_tonumber(L, 5);
            height = 10;
            break;
        default:
            width = lua_tonumber(L, 5);
            height = lua_tonumber(L, 6);
    }
    hp = lua_tonumber(L, 1);
    max = lua_tonumber(L, 2);
    x = lua_tonumber(L, 3);
    y = lua_tonumber(L, 4);
    gui_draw_healthbar(x, y, width, height, hp, max);
    return 0;
}

/*
 * Lua hook to the function:
 * gui_draw_textbox( int x, int y, int width, int height,
 *   const GLfloat box_color[], const GLfloat trim_color[],
 *   const GLfloat font_color[], const char *string );
 */
int gui_lua_drawTextBox( lua_State *L ) {
    int x;
    int y;
    int width;
    int height;
    const char *string;
    GLfloat font_color[] = {0.5f, 0.5f, 0.5f, 1.0f};
    GLfloat box_color[] = {0.0f, 0.0f, 0.0f, 1.0f};
    GLfloat trim_color[] = {0.0f, 0.0f, 0.0f, 1.0f};
    switch (lua_gettop(L)) { /* number of elements */
        case 0:
        case 1:
        case 2:
        case 3:
        case 4:
            lua_pushstring(L, "Too few arguments");
            lua_error(L);
        default:
        case 8:
            lua_rawgeti(L, 8, 1);
            lua_rawgeti(L, 8, 2);
            lua_rawgeti(L, 8, 3);
            lua_rawgeti(L, 8, 4);
            if( lua_isnoneornil(L, 12) ) {
                trim_color[3] = 1.0f;
            }
            else {
                trim_color[3] = (float)lua_tonumber(L, 12);
            }
            trim_color[2] = (float)lua_tonumber(L, 11);
            trim_color[1] = (float)lua_tonumber(L, 10);
            trim_color[0] = (float)lua_tonumber(L, 9);
            lua_pop(L, 5);
        case 7:
            lua_rawgeti(L, 7, 1);
            lua_rawgeti(L, 7, 2);
            lua_rawgeti(L, 7, 3);
            lua_rawgeti(L, 7, 4);
            if( lua_isnoneornil(L, 11) ) {
                box_color[3] = 1.0f;
            }
            else {
                box_color[3] = (float)lua_tonumber(L, 11);
            }
            box_color[2] = (float)lua_tonumber(L, 10);
            box_color[1] = (float)lua_tonumber(L, 9);
            box_color[0] = (float)lua_tonumber(L, 8);
            lua_pop(L, 5);
        case 6:
            lua_rawgeti(L, 6, 1);
            lua_rawgeti(L, 6, 2);
            lua_rawgeti(L, 6, 3);
            lua_rawgeti(L, 6, 4);
            if( lua_isnoneornil(L, 10) ) {
                font_color[3] = 1.0f;
            }
            else {
                font_color[3] = (float)lua_tonumber(L, 10);
            }
            font_color[2] = (float)lua_tonumber(L, 9);
            font_color[1] = (float)lua_tonumber(L, 8);
            font_color[0] = (float)lua_tonumber(L, 7);
            lua_pop(L, 5);
        case 5:
            x = lua_tonumber(L, 1);
            y = lua_tonumber(L, 2);
            width = lua_tonumber(L, 3);
            height = lua_tonumber(L, 4);
            string = lua_tostring(L, 5);
    }
    gui_draw_textbox(x, y, width, height, box_color, trim_color, font_color,
        string);
    return 0;
}

/*
 * Lua hook to the function:
 * gui_draw_big_textbox( int x, int y, int width, int height,
 *   const GLfloat box_color[], const GLfloat trim_color[],
 *   const GLfloat font_color[], const char *string );
 */
int gui_lua_drawBigTextBox( lua_State *L ) {
    int x;
    int y;
    int width;
    int height;
    const char *string;
    GLfloat font_color[] = {0.5f, 0.5f, 0.5f, 1.0f};
    GLfloat box_color[] = {0.0f, 0.0f, 0.0f, 1.0f};
    GLfloat trim_color[] = {0.0f, 0.0f, 0.0f, 1.0f};
    switch (lua_gettop(L)) { /* number of elements */
        case 0:
        case 1:
        case 2:
        case 3:
        case 4:
            lua_pushstring(L, "Too few arguments");
            lua_error(L);
        default:
        case 8:
            lua_rawgeti(L, 8, 1);
            lua_rawgeti(L, 8, 2);
            lua_rawgeti(L, 8, 3);
            lua_rawgeti(L, 8, 4);
            if( lua_isnoneornil(L, 12) ) {
                trim_color[3] = 1.0f;
            }
            else {
                trim_color[3] = (float)lua_tonumber(L, 12);
            }
            trim_color[2] = (float)lua_tonumber(L, 11);
            trim_color[1] = (float)lua_tonumber(L, 10);
            trim_color[0] = (float)lua_tonumber(L, 9);
            lua_pop(L, 5);
        case 7:
            lua_rawgeti(L, 7, 1);
            lua_rawgeti(L, 7, 2);
            lua_rawgeti(L, 7, 3);
            lua_rawgeti(L, 7, 4);
            if( lua_isnoneornil(L, 11) ) {
                box_color[3] = 1.0f;
            }
            else {
                box_color[3] = (float)lua_tonumber(L, 11);
            }
            box_color[2] = (float)lua_tonumber(L, 10);
            box_color[1] = (float)lua_tonumber(L, 9);
            box_color[0] = (float)lua_tonumber(L, 8);
            lua_pop(L, 5);
        case 6:
            lua_rawgeti(L, 6, 1);
            lua_rawgeti(L, 6, 2);
            lua_rawgeti(L, 6, 3);
            lua_rawgeti(L, 6, 4);
            if( lua_isnoneornil(L, 10) ) {
                font_color[3] = 1.0f;
            }
            else {
                font_color[3] = (float)lua_tonumber(L, 10);
            }
            font_color[2] = (float)lua_tonumber(L, 9);
            font_color[1] = (float)lua_tonumber(L, 8);
            font_color[0] = (float)lua_tonumber(L, 7);
            lua_pop(L, 5);
        case 5:
            x = lua_tonumber(L, 1);
            y = lua_tonumber(L, 2);
            width = lua_tonumber(L, 3);
            height = lua_tonumber(L, 4);
            string = lua_tostring(L, 5);
    }
    gui_draw_big_textbox(x, y, width, height, box_color, trim_color, font_color,
        string);
    return 0;
}

/*
 * Lua stand-alone C function hook. Returns the player's current HP.
 */
 /*
int gui_lua_getPlayerHP( lua_State *L ) {
    if( gui_lua_initialized ) {
        lua_pushnumber(L, ((go_stats*)player->stats)->hp); * TODO: remove GO dependency *
        return 1;
    }
    else {
        printerr( ERROR_LUA_NOINIT );
        return 0;
    }
}
*/

/*
 * Returns true iff the Lua state for the GUI is initialized.
 */
int lua_gui_is_initialized() {
    return gui_lua_initialized;
}

/*
 * Initializes the Lua GUI state and registers all of the function hooks.
 * Also runs "init" for the default gui.lua script.
 */
int lua_gui_initialize() {
    int status;
    if( !gui_lua_initialized ) {
        luaR_package_create();
        luaR_package_add("drawTextBox", gui_lua_drawTextBox);
        luaR_package_add("drawHealthBar", gui_lua_drawHealthBar);
        luaR_package_add("loadImage", gui_lua_loadPng);
        luaR_package_add("drawImage", gui_lua_drawTexture);
        /*luaR_package_add("getPlayerHP", gui_lua_getPlayerHP);*/
        luaR_package_add("drawBigTextBox", gui_lua_drawBigTextBox);
        luaR_package_set("RG_GUI");

        luaR_load_file("scripts/gui.lua");
        player = player_get();

        gui_lua_initialized = 1;
        return 0;
    }
    else {
        printerr( WARNING_LUA_REINIT );
        return 1;
    }
}

/*
 * Calls the function "display" in the Lua GUI script. "display" should be a
 * function in the Lua GUI script that draws the user interface.
 */
int lua_gui_run() {
    int status;
    if( gui_lua_initialized ) {
        luaR_fcall("display");
    }
    else {
        printerr( ERROR_LUA_NOINIT );
    }
    return 0;
}
